import os
import uuid
import logging
import logging.config
import yaml
import contextvars
import signal
from pathlib import Path

# 创建上下文变量来存储请求ID
request_id_var = contextvars.ContextVar('request_id', default=None)

class RequestIdFilter(logging.Filter):
    """为日志添加请求ID的过滤器"""
    def filter(self, record):
        request_id = request_id_var.get()
        record.request_id = request_id if request_id else 'no-request-id'
        return True

def get_request_id():
    """获取当前请求ID，如果不存在则创建"""
    request_id = request_id_var.get()
    if request_id is None:
        request_id = str(uuid.uuid4())
        request_id_var.set(request_id)
    return request_id

# 配置文件路径和上次修改时间
config_file = None
last_mtime = 0

def setup_logging(env=None):
    """根据环境变量或参数加载不同的配置文件"""
    global config_file
    
    if env is None:
        env = os.environ.get('APP_ENV', 'development')
    
    # 使用绝对路径
    base_dir = Path(__file__).resolve().parent.parent.parent
    config_file = base_dir / 'config' / f'logging_config_{env}.yaml'
    
    if config_file.exists():
        with open(config_file, 'r', encoding='utf-8') as f:
            config = yaml.safe_load(f)
            
            # 从环境变量覆盖日志级别
            env_level = os.environ.get('LOG_LEVEL')
            if env_level:
                config['root']['level'] = env_level
                # 也可以覆盖特定记录器的级别
                for logger_name, logger_config in config.get('loggers', {}).items():
                    logger_env_var = f'LOG_LEVEL_{logger_name.replace(".", "_").upper()}'
                    logger_level = os.environ.get(logger_env_var)
                    if logger_level:
                        logger_config['level'] = logger_level
            
            # 确保日志目录存在
            log_dir = base_dir / 'logs'
            log_dir.mkdir(exist_ok=True)
            
            # 更新配置中的文件路径为绝对路径
            for handler_name, handler in config.get('handlers', {}).items():
                if 'filename' in handler:
                    handler['filename'] = str(log_dir / Path(handler['filename']).name)
            
            logging.config.dictConfig(config)
            logging.info(f"已加载{env}环境的日志配置")
            
            # 记录上次修改时间
            global last_mtime
            last_mtime = config_file.stat().st_mtime
    else:
        # 配置文件不存在时的应急方案
        logging.basicConfig(level=logging.INFO)
        logging.warning(f"配置文件{config_file}不存在，使用默认配置")

def check_config_changed():
    """检查配置文件是否已更改"""
    global last_mtime, config_file
    try:
        if config_file and config_file.exists():
            mtime = config_file.stat().st_mtime
            if mtime > last_mtime:
                last_mtime = mtime
                return True
    except OSError:
        pass
    return False

def reload_config(signum=None, frame=None):
    """重新加载日志配置"""
    if check_config_changed() or signum is not None:
        try:
            with open(config_file, 'r', encoding='utf-8') as f:
                config = yaml.safe_load(f)
                logging.config.dictConfig(config)
                logging.info("日志配置已重新加载")
        except Exception as e:
            logging.error(f"重新加载日志配置失败: {e}")

# 注册信号处理器（在Windows上可能不支持SIGHUP）
try:
    signal.signal(signal.SIGHUP, reload_config)
except (AttributeError, ValueError):
    logging.warning("当前平台不支持SIGHUP信号，日志配置热重载功能将不可用")